from Tkinter import *
from Canvas import *
import sys
import random
from math import *
from HomVec3 import *
from matrix import *
WIDTH  = 400 # width of canvas
HEIGHT = 400 # height of canvas

HPSIZE = 1 # double of point size (must be integer)
COLOR = "#0000FF" # blue

tp=[]
pointList = [] # list of points (used by Canvas.delete(...))

boundingbox={'x':None,'-x':None,'y':None,'-y':None,'z':None,'-z':None}

scale = None

mid=None

def quit(root=None):
    """ quit programm """
    if root==None:
        sys.exit(0)
    root._root().quit()
    root._root().destroy()

def actBBox(param):
    global boundingbox

    for ele in param.keys():
        if boundingbox['-%s'%ele] > param[ele] or not boundingbox['-%s'%ele]:
            boundingbox['-%s'%ele]=param[ele]
        if boundingbox['%s'%ele] < param[ele] or not boundingbox['%s'%ele]:
            boundingbox['%s'%ele]=param[ele]

def getPoints(fname):
    global pointList
    for line in open(fname):
        x,y,z=map(float,line.split())
        actBBox({"x":x,"y":y,"z":z})
        pointList.append(HomVec3(x,y,z,1))
        
    print "Punkte eingelesen --> Boundingbox erstellt"
   
def getMid():
  global mid,boundingbox    
  p = HomVec3(boundingbox['-x'],boundingbox['-y'],boundingbox['-z'],1)
  q = HomVec3(boundingbox['x'],boundingbox['y'],boundingbox['z'],1)
  mid = (p+q) / 2
  
  return mid

def getScale():
    return 2.0 / max(abs(boundingbox['x']-boundingbox['-x']),
    abs(boundingbox['y']-boundingbox['-y']),abs(boundingbox['z']-boundingbox['-z']))
    
def getNewPoints():
  global pointList,matrix,mid,scale,tp
  
  tp=[HomVec3( ((p.x-mid.x)*scale),((p.y-mid.y)*scale),((p.z-mid.z)*scale),1) for p in pointList]
  
    
def draw():
    
    global tp
    #transform to viewpoint
    vp = [[(p.x+1)*WIDTH/2.0, (1-p.y)*HEIGHT/2.0] for p in tp]
    new=[]
    for p in vp:
      x,y=p[0],p[1]
      p=can.create_oval(x-HPSIZE, y-HPSIZE, x+HPSIZE, y+HPSIZE,fill=COLOR, outline=COLOR)
     
def rotYp():
    """ rotate counterclockwise around y axis """
    global tp 
    angle = 10*pi/180
   
    tp=[HomVec3(cos(angle)*p.x-sin(angle)*p.z, p.y, sin(angle)*p.x+cos(angle)*p.z,1) for p in tp]
   
    can.delete(*pointList)
    draw()

def rotYn():
    
    global tp 
    angle = -10*pi/180
   
    tp=[HomVec3(cos(angle)*p.x-sin(angle)*p.z, p.y, sin(angle)*p.x+cos(angle)*p.z,1) for p in tp]
   
    can.delete(*pointList)
    draw()


if __name__ == "__main__":
 
    global pointList,scale
    #check parameters
    if len(sys.argv) != 1:
       print "pointViewerTemplate.py"
       sys.exit(-1)

    # create main window
    mw = Tk()

    # create and position canvas and buttons
    cFr = Frame(mw, width=WIDTH, height=HEIGHT, relief="sunken", bd=1)
    cFr.pack(side="top")
    can = Canvas(cFr, width=WIDTH, height=HEIGHT)
    can.pack()
    bFr = Frame(mw)
    bFr.pack(side="left")
    bRotYn = Button(bFr, text="<-", command=rotYn)
    bRotYn.pack(side="left")
    bRotYp = Button(bFr, text="->", command=rotYp)
    bRotYp.pack(side="left")
    eFr = Frame(mw)
    eFr.pack(side="right")
    bExit = Button(eFr, text="Quit", command=(lambda root=mw: quit(root)))
    bExit.pack()

    # read Points
    getPoints("squirrel_points.raw")
    
   
    
    #Mittelpunkt ermitteln
    mid = getMid()
   
    #Skalierungsfaktor
    scale=getScale()
    
    getNewPoints()
    
    # draw points
    draw()
  
    # start
    mw.mainloop()
    
